//---------------------------------------------------------------------------------
// Copyright (c) 2011, Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//---------------------------------------------------------------------------------

namespace Microsoft.Samples.ServiceBus.SilverlightChat.Models.Commands
{
    using System;
    using System.Windows;
    using System.Windows.Input;
    using Microsoft.Samples.AccessControl;
    using Microsoft.Samples.ServiceBus.SilverlightChat.Models.ViewModels;

    /// <summary>
    /// Encapsulates a command to acquire an Access Control Service token and initialize the
    /// application's context.
    /// </summary>
    public class LoginCommand : ICommand
    {
        private readonly LoginWindowViewModel viewModel;

        public LoginCommand(LoginWindowViewModel viewModel)
        {
            if (viewModel == null)
            {
                throw new ArgumentNullException("viewModel");
            }

            this.viewModel = viewModel;
        }

        public event EventHandler CanExecuteChanged;

        public LoginWindowViewModel ViewModel
        {
            get { return this.viewModel; }
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            // Login might take a little while - update the UI to show an indeterminate progress bar
            VisualStateManager.GoToState(this.ViewModel.Window, "LoggingIn", false);

            // Asynchronously begin a request to get an auth token from ACS - call LoginCompleted 
            // when the request completes
            App.Context.TokenProvider.BeginGetToken(false, this.LoginCompleted, null);
        }

        public void LoginCompleted(IAsyncResult result)
        {
            SimpleWebToken token;

            try
            {
                // End the async request - if it failed, an exception will be thrown here
                token = App.Context.TokenProvider.EndGetToken(result);

                // Update the UI and navigate to the main page
                this.ViewModel.Dispatcher.BeginInvoke(() =>
                {
                    // Initialize the App: this initializes a messaging factory and namespace client
                    // and also begins a timer to renew this token a few minutes before it expires.
                    App.Context.CompleteAuthentication(this.ViewModel.UserName);

                    var mainPage = (MainPage)App.Current.RootVisual;

                    // Begin loading the main UI - these calls will start a loop which periodically
                    // checks for new Topics and Subscriptions
                    var chatWindowViewModel = new ChatWindowViewModel(mainPage.chatWindow);
                    chatWindowViewModel.Topics.AutoRefresh = true;
                    chatWindowViewModel.Topics.OnRefreshTopics(true);

                    mainPage.chatWindow.DataContext = chatWindowViewModel;

                    // Update the UI to show the 'Chat' surface
                    VisualStateManager.GoToState(mainPage, "Chat", true);
                });
            }
            catch (Exception e)
            {
                App.ShowError(e);
            }
        }

        protected void OnCanExecuteChanged(object sender, EventArgs e)
        {
            if (this.CanExecuteChanged != null)
            {
                this.CanExecuteChanged(sender, e);
            }
        }
    }
}
